#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
PyQt6 Modbus采集调试页面
提供Modbus设备连接和数据采集功能
"""

from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
                            QGroupBox, QPushButton, QLabel, QLineEdit, 
                            QComboBox, QRadioButton, QScrollArea,
                            QFrame, QSizePolicy, QApplication)
from PyQt6.QtCore import pyqtSignal, Qt
from PyQt6.QtGui import QFont

from utils.communication import ModbusCollectionManager
from gui.components.pyqt6_log_component import PyQt6LogComponent


class ModbusCollectionPage(QWidget):
    """Modbus采集调试页面类"""
    
    def __init__(self):
        """初始化Modbus采集页面"""
        super().__init__()
        self.title = "Modbus采集调试"
        
        # 初始化通信管理器
        self.modbus_collection_manager = ModbusCollectionManager(self._modbus_message_callback)
        
        # 初始化界面
        self._init_ui()
    
    def _init_ui(self):
        """初始化UI界面"""
        # 设置主布局
        main_layout = QHBoxLayout(self)
        main_layout.setContentsMargins(15, 15, 15, 15)
        main_layout.setSpacing(15)
        
        # 左侧控制面板
        control_panel = self._create_control_panel()
        main_layout.addWidget(control_panel, 1)
        
        # 右侧日志面板
        log_panel = self._create_log_panel()
        main_layout.addWidget(log_panel, 3)
        
        # 设置整体样式
        self._setup_styles()
    
    def _setup_styles(self):
        """设置界面样式"""
        # 设置字体
        font = QFont("Arial", 10)
        self.setFont(font)
        
        # 为所有GroupBox设置样式
        for group_box in self.findChildren(QGroupBox):
            group_box.setStyleSheet("""
                QGroupBox {
                    font-weight: bold;
                    border: 1px solid gray;
                    border-radius: 5px;
                    margin-top: 1ex;
                }
                QGroupBox::title {
                    subline-offset: -2px;
                    padding: 0 5px;
                }
            """)
    
    def _create_control_panel(self):
        """创建控制面板"""
        # 外层滚动区域
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)

        # 滚动区域的内容部件
        container = QWidget()
        layout = QVBoxLayout(container)
        layout.setSpacing(15)

        # 协议选择组
        protocol_group = QGroupBox("协议选择")
        protocol_layout = QVBoxLayout(protocol_group)
        protocol_layout.setSpacing(8)
        
        self.tcp_radio = QRadioButton("Modbus TCP")
        self.rtu_radio = QRadioButton("Modbus RTU")
        self.tcp_radio.setChecked(True)
        
        # 设置RadioButton样式
        self.tcp_radio.setStyleSheet("""
            QRadioButton {
                spacing: 5px;
            }
            QRadioButton::indicator {
                width: 18px;
                height: 18px;
            }
        """)
        
        self.rtu_radio.setStyleSheet("""
            QRadioButton {
                spacing: 5px;
            }
            QRadioButton::indicator {
                width: 18px;
                height: 18px;
            }
        """)
        
        self.tcp_radio.toggled.connect(self._on_protocol_change)
        self.rtu_radio.toggled.connect(self._on_protocol_change)
        
        protocol_layout.addWidget(self.tcp_radio)
        protocol_layout.addWidget(self.rtu_radio)
        
        # 连接配置组
        self.connection_group = QGroupBox("连接配置")
        self.connection_layout = QGridLayout(self.connection_group)
        self.connection_layout.setSpacing(12)
        self.connection_layout.setContentsMargins(10, 15, 10, 15)
        
        # 创建TCP配置（默认）
        self._create_tcp_config()
        
        # HEX命令发送组
        command_group = QGroupBox("HEX命令发送")
        command_layout = QVBoxLayout(command_group)
        command_layout.setSpacing(10)
        
        command_layout.addWidget(QLabel("HEX命令:"))
        self.hex_command_edit = QLineEdit("01 03 00 00 00 06")
        self.hex_command_edit.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            QLineEdit:focus {
                border-color: #4A90E2;
            }
        """)
        command_layout.addWidget(self.hex_command_edit)
        
        self.send_command_btn = QPushButton("发送命令")
        self.send_command_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:pressed {
                background-color: #3d8b40;
            }
        """)
        self.send_command_btn.clicked.connect(self._send_hex_command)
        command_layout.addWidget(self.send_command_btn)
        
        # 状态信息组
        status_group = QGroupBox("状态信息")
        status_layout = QVBoxLayout(status_group)
        status_layout.setSpacing(8)
        
        self.connection_status_label = QLabel("连接状态: 未连接")
        self.last_operation_label = QLabel("最后操作: -")
        
        # 设置状态标签样式
        self.connection_status_label.setStyleSheet("""
            QLabel {
                color: #333;
                font-weight: bold;
            }
        """)
        
        self.last_operation_label.setStyleSheet("""
            QLabel {
                color: #333;
                font-weight: bold;
            }
        """)
        
        status_layout.addWidget(self.connection_status_label)
        status_layout.addWidget(self.last_operation_label)
        
        # 连接/断开按钮
        self.connect_btn = QPushButton("连接设备")
        self.connect_btn.setStyleSheet("""
            QPushButton {
                background-color: #2196F3;
                color: white;
                border: none;
                padding: 12px;
                border-radius: 4px;
                font-weight: bold;
                font-size: 11px;
            }
            QPushButton:hover {
                background-color: #1976D2;
            }
            QPushButton:pressed {
                background-color: #0D47A1;
            }
        """)
        self.connect_btn.clicked.connect(self._connect_device)
        
        # 添加到主布局
        layout.addWidget(protocol_group)
        layout.addWidget(self.connection_group)
        layout.addWidget(command_group)
        layout.addWidget(status_group)
        layout.addWidget(self.connect_btn)
        layout.addStretch()
        
        scroll_area.setWidget(container)
        return scroll_area
    
    def _create_tcp_config(self):
        """创建TCP配置控件"""
        # 清空配置布局
        for i in reversed(range(self.connection_layout.count())):
            widget = self.connection_layout.itemAt(i).widget()
            if widget:
                widget.setParent(None)
        
        self.connection_group.setTitle("连接配置 (TCP)")
        
        # IP地址
        ip_label = QLabel("设备IP:")
        ip_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(ip_label, 0, 0)
        self.device_ip_edit = QLineEdit("127.0.0.1")
        self.device_ip_edit.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        self.connection_layout.addWidget(self.device_ip_edit, 0, 1)
        
        # 端口
        port_label = QLabel("端口:")
        port_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(port_label, 1, 0)
        self.device_port_edit = QLineEdit("5020")
        self.device_port_edit.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        self.connection_layout.addWidget(self.device_port_edit, 1, 1)
    
    def _create_rtu_config(self):
        """创建RTU配置控件"""
        # 清空配置布局
        for i in reversed(range(self.connection_layout.count())):
            widget = self.connection_layout.itemAt(i).widget()
            if widget:
                widget.setParent(None)
        
        self.connection_group.setTitle("连接配置 (RTU)")
        
        # 串口
        port_label = QLabel("串口:")
        port_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(port_label, 0, 0)
        self.rtu_port_combo = QComboBox()
        self.rtu_port_combo.setStyleSheet("""
            QComboBox {
                padding: 6px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            QComboBox::drop-down {
                border: none;
            }
        """)
        self.connection_layout.addWidget(self.rtu_port_combo, 0, 1)
        
        # 波特率
        baudrate_label = QLabel("波特率:")
        baudrate_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(baudrate_label, 1, 0)
        self.rtu_baudrate_combo = QComboBox()
        self.rtu_baudrate_combo.addItems(['9600', '19200', '38400', '57600', '115200'])
        self.rtu_baudrate_combo.setCurrentText('9600')
        self.rtu_baudrate_combo.setStyleSheet("""
            QComboBox {
                padding: 6px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        self.connection_layout.addWidget(self.rtu_baudrate_combo, 1, 1)
        
        # 数据位
        bytesize_label = QLabel("数据位:")
        bytesize_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(bytesize_label, 2, 0)
        self.rtu_bytesize_combo = QComboBox()
        self.rtu_bytesize_combo.addItems(['7', '8'])
        self.rtu_bytesize_combo.setCurrentText('8')
        self.rtu_bytesize_combo.setStyleSheet("""
            QComboBox {
                padding: 6px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        self.connection_layout.addWidget(self.rtu_bytesize_combo, 2, 1)
        
        # 校验位
        parity_label = QLabel("校验位:")
        parity_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(parity_label, 3, 0)
        self.rtu_parity_combo = QComboBox()
        self.rtu_parity_combo.addItems(['N', 'E', 'O'])
        self.rtu_parity_combo.setCurrentText('N')
        self.rtu_parity_combo.setStyleSheet("""
            QComboBox {
                padding: 6px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        self.connection_layout.addWidget(self.rtu_parity_combo, 3, 1)
        
        # 停止位
        stopbits_label = QLabel("停止位:")
        stopbits_label.setStyleSheet("QLabel { font-weight: bold; }")
        self.connection_layout.addWidget(stopbits_label, 4, 0)
        self.rtu_stopbits_combo = QComboBox()
        self.rtu_stopbits_combo.addItems(['1', '2'])
        self.rtu_stopbits_combo.setCurrentText('1')
        self.rtu_stopbits_combo.setStyleSheet("""
            QComboBox {
                padding: 6px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        self.connection_layout.addWidget(self.rtu_stopbits_combo, 4, 1)
        
        # 刷新串口按钮
        refresh_btn = QPushButton("刷新串口")
        refresh_btn.setStyleSheet("""
            QPushButton {
                background-color: #FF9800;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #F57C00;
            }
            QPushButton:pressed {
                background-color: #EF6C00;
            }
        """)
        refresh_btn.clicked.connect(self._refresh_rtu_ports)
        self.connection_layout.addWidget(refresh_btn, 5, 0, 1, 2)
        
        # 刷新串口列表
        self._refresh_rtu_ports()
    
    def _refresh_rtu_ports(self):
        """刷新RTU串口列表"""
        try:
            import serial.tools.list_ports
            ports = [port.device for port in serial.tools.list_ports.comports()]
            self.rtu_port_combo.clear()
            self.rtu_port_combo.addItems(ports)
        except Exception as e:
            self.log_component.log_message(f"刷新串口列表失败: {e}", "ERROR")
    
    def _create_log_panel(self):
        """创建日志面板"""
        self.log_component = PyQt6LogComponent(self, "Modbus日志", 20)
        return self.log_component
    
    def _on_protocol_change(self):
        """协议切换事件处理"""
        if self.tcp_radio.isChecked():
            self._create_tcp_config()
        else:
            self._create_rtu_config()
    
    def _connect_device(self):
        """连接Modbus设备"""
        try:
            if self.tcp_radio.isChecked():
                ip = self.device_ip_edit.text().strip()
                port = int(self.device_port_edit.text().strip())

                if self.modbus_collection_manager.connect_tcp(ip, port):
                    self.connection_status_label.setText(f"连接状态: 已连接TCP {ip}:{port}")
                    self.connect_btn.setText("断开设备")
                    self.connect_btn.clicked.disconnect()
                    self.connect_btn.clicked.connect(self._disconnect_device)
                    self.log_component.log_message(f"连接Modbus TCP设备成功: {ip}:{port}")
                else:
                    self.log_component.log_message("连接Modbus TCP设备失败", "ERROR")
            else:  # RTU
                port = self.rtu_port_combo.currentText().strip()
                baudrate = int(self.rtu_baudrate_combo.currentText())
                bytesize = int(self.rtu_bytesize_combo.currentText())
                parity = self.rtu_parity_combo.currentText()
                stopbits = int(self.rtu_stopbits_combo.currentText())

                if not port:
                    self.log_component.log_message("请选择串口", "WARNING")
                    return

                if self.modbus_collection_manager.connect_rtu(port, baudrate, bytesize, parity, stopbits):
                    self.connection_status_label.setText(f"连接状态: 已连接RTU {port}@{baudrate}")
                    self.connect_btn.setText("断开设备")
                    self.connect_btn.clicked.disconnect()
                    self.connect_btn.clicked.connect(self._disconnect_device)
                    self.log_component.log_message(f"连接Modbus RTU设备成功: {port}@{baudrate}")
                else:
                    self.log_component.log_message("连接Modbus RTU设备失败", "ERROR")
                    
        except Exception as e:
            self.log_component.log_message(f"连接设备失败: {e}", "ERROR")
    
    def _disconnect_device(self):
        """断开Modbus设备连接"""
        try:
            if self.tcp_radio.isChecked():
                self.modbus_collection_manager.disconnect_tcp()
            else:  # RTU
                self.modbus_collection_manager.disconnect_rtu()
            
            self.connection_status_label.setText("连接状态: 未连接")
            self.connect_btn.setText("连接设备")
            self.connect_btn.clicked.disconnect()
            self.connect_btn.clicked.connect(self._connect_device)
            self.log_component.log_message("已断开设备连接")
        except Exception as e:
            self.log_component.log_message(f"断开设备连接错误: {e}", "ERROR")
    
    def _send_hex_command(self):
        """发送HEX命令"""
        hex_command = self.hex_command_edit.text().strip()
        if not hex_command:
            self.log_component.log_message("请输入HEX命令", "WARNING")
            return
        
        try:
            if self.modbus_collection_manager.send_command(hex_command):
                self.last_operation_label.setText("最后操作: 发送成功")
                self.log_component.log_message(f"发送HEX命令: {hex_command}", "INFO", "send")
            else:
                self.log_component.log_message("发送HEX命令失败", "ERROR")
        except Exception as e:
            self.log_component.log_message(f"发送HEX命令失败: {e}", "ERROR")
    
    def _modbus_message_callback(self, message: str, level: str = "INFO", msg_type: str = "normal"):
        """Modbus消息回调"""
        self.log_component.log_message(message, level, msg_type)
    
    def on_close(self):
        """页面关闭时的清理"""
        try:
            self.modbus_collection_manager.disconnect_tcp()
            self.modbus_collection_manager.disconnect_rtu()
        except:
            pass


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    window = ModbusCollectionPage()
    window.show()
    sys.exit(app.exec())